package com.tanhua.server.service;

import cn.hutool.core.util.StrUtil;
import com.alibaba.fastjson.JSON;
import com.baomidou.mybatisplus.core.conditions.Wrapper;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.tanhua.common.exception.BusinessException;
import com.tanhua.common.mapper.AdminMapper;
import com.tanhua.common.pojo.Admin;
import com.tanhua.common.pojo.User;
import com.tanhua.common.utils.AdminThreadLocal;
import com.tanhua.common.utils.UserThreadLocal;
import com.tanhua.common.vo.ErrorResult;
import com.tanhua.server.vo.AdminVo;
import io.jsonwebtoken.Jwts;
import io.jsonwebtoken.SignatureAlgorithm;
import org.joda.time.DateTime;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Service;

import java.util.HashMap;
import java.util.Map;

@Service
public class SystemService {
    @Autowired
    private AdminMapper adminMapper;

    @Value("${jwt.secret}")
    private String secret;

    @Autowired
    private RedisTemplate<String,String> redisTemplate;

    /**
     * 登录
     * @param param
     * @return
     */
    public Map<String, Object> login(Map<String, String> param) {
        String username = param.get("username");
        String password = param.get("password");
        String myCode = param.get("verificationCode");
        String uuid = param.get("uuid");

        String verificationCode = redisTemplate.opsForValue().get(uuid);
        //取出redis种的验证码,判断验证码
        if (!StrUtil.equalsIgnoreCase(myCode,verificationCode)){
            throw new BusinessException(ErrorResult.codeError());
        }

        //判断用户名和密码是否正确:从mysql中取出用户名和密码
        LambdaQueryWrapper<Admin> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(Admin::getUsername,username).eq(Admin::getPassword,password);
        Admin admin = adminMapper.selectOne(wrapper);
        if (admin == null){
            throw new BusinessException(ErrorResult.nameAndPwdError());
        }

        //登入后要把redis中的验证码删除,以防再次输入
        redisTemplate.delete(uuid);

        //利用jwt设置token
        Map<String, Object> claims = new HashMap<String, Object>();
        claims.put("username", admin.getUsername());//用户名
        claims.put("id", admin.getUid());//用户id

        //生成token
        String token = Jwts.builder()
                .setClaims(claims) //payload，存放数据的位置，不能放置敏感数据，如：密码等
                .signWith(SignatureAlgorithm.HS256, secret) //设置加密方法和加密盐
                .setExpiration(new DateTime().plusHours(12).toDate()) //设置过期时间，12小时后过期
                .compact();

        Map<String, Object> map=new HashMap<>();
        map.put("token",token);

        return map;
    }

    /**
     * TODO
     * 登出
     */
    public void logout() {
        AdminThreadLocal.remove();
    }

    /**
     * TODO
     * 用户基础信息:用户名,用户id和头像
     * @return  返回AdminVo
     */
    public AdminVo profile() {
        //解析token
        Admin admin = AdminThreadLocal.get();
        //返回adminVo
        AdminVo adminVo = new AdminVo();
        adminVo.setUid(admin.getUid());
        adminVo.setUsername(admin.getUsername());
        adminVo.setAvatar("http://xswtanhua.oss-cn-hangzhou.aliyuncs.com/images/2022/01/13/16420884262526931.jpg");
        return adminVo;
    }

    //TODO 解析token
    public Admin queryToken(String token){
        try{
            // 通过token解析数据
            Map<String, Object> body = Jwts.parser()
                    .setSigningKey(secret)//盐值要相同
                    .parseClaimsJws(token)
                    .getBody();
            //将json格式的body数据装换成user对象
            ObjectMapper objectMapper = new ObjectMapper();
            String json = objectMapper.writeValueAsString(body);
            Admin admin = JSON.parseObject(json, Admin.class);
            return admin;
        }catch (Exception e){
            throw new BusinessException(ErrorResult.tokenFail());
        }

    }



}
